package org.jkuang.qstar.index.iterator;

import java.util.Comparator;

import org.jkuang.qstar.index.store.DataBlock;

/**
 * 分时迭代器，队列扫描完MAX_SCAN_COUNT 个数之后发现没有满足条件的数据也先让出cpu返回当前虚节点
 * 当其他节点均优先于该队列首节点时候，该节点将不用再进行扫描
 * 
 * @author jkuang
 * 
 */
public class NodeIterator<T> implements TSIterator<T> {

	protected T begin, end, indexNode;
	protected boolean desc;
	protected boolean virtual;
	protected SubList<T> nodeIterator;
	protected final SubList<DataBlock<T>> subList;
	protected final TSIterFilter<T> filter;
	protected final Comparator<T> comparator;

	/**
	 * 
	 * @param blocks
	 * @param fromIndex
	 * @param toIndex
	 * @param begin
	 * @param end
	 * @param desc
	 */
	public NodeIterator(Comparator<T> comparator, TSIterFilter<T> filter, DataBlock<T>[] blocks, int fromIndex,
			int toIndex, T begin, T end, boolean desc) {
		this.end = end;
		this.begin = begin;
		this.desc = desc;
		this.filter = filter;
		this.comparator = comparator;
		this.subList = new SubList<DataBlock<T>>(blocks, fromIndex, toIndex, desc);

	}

	/**
	 * 计算索引列上数据数量
	 * 
	 * @return
	 */
	public int scanSize() {
		int total = 0;
		for (int index = 0; index < subList.size(); index++) {
			if (index == 0 || index == subList.size() - 1) {
				total += subList.get(index).nodeList(begin, end, desc).size();
			} else {
				total += subList.get(index).size();
			}
		}
		return total;
	}

	/**
	 * 判断当前索引是否还有元素
	 * 
	 * @return
	 */
	public boolean iterHasNext() {
		while (this.nodeIterator == null || !this.nodeIterator.hasNext()) {
			if (this.subList.hasNext()) {
				this.nodeIterator = this.subList.next().nodeList(begin, end, desc);
			} else {
				return false;
			}
		}
		return true;
	}

	/**
	 * 迭代下一个元素
	 * 
	 * @return
	 */
	public T iterNext() {
		if (iterHasNext()) {
			return nodeIterator.next();
		} else {
			return null;
		}
	}

	@Override
	public T peek() {
		hasNext();
		return indexNode;
	}

	@Override
	public T next() {
		hasNext();
		T temp = indexNode;
		indexNode = null;
		return temp;
	}

	@Override
	public int compareTo(TSIterator<T> o) {
		if (desc) {
			return -this.comparator.compare(peek(), o.peek());
		} else {
			return this.comparator.compare(peek(), o.peek());
		}
	}

	@Override
	public boolean hasNext() {
		if (indexNode != null) {
			return true;
		}
		int count = 0;
		while (iterHasNext()) {
			T node = iterNext();
			if (filter == null || filter.contains(node)) {
				indexNode = node;
				virtual = false;
				return true;
			}
			// 使CPU停顿，当前已寻找过的node有可能已经满足
			else if (count++ >= MAX_SCAN_COUNT) {
				indexNode = node;
				virtual = true;
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean isVirtual() {
		// TODO Auto-generated method stub
		return virtual;
	}

}
